#include "proxy/cfg/localconfiginstance.h"
#include "proxy/base/proxybase.h"
#include "json/json.h"

namespace proxy{

  ConfigInstance* ConfigInstance::instance_ = NULL;

  ConfigInstance* ConfigInstance::GetConfigInstance(){
    if (instance_ == NULL){
      instance_ = new ConfigInstance();
      return instance_;
    }
    return instance_;
  }
  ConfigInstance::ConfigInstance(){

  }
  ConfigInstance::~ConfigInstance(){

  }

  bool ConfigInstance::InitConfigWithFile(const std::string path_name){
    FILE *fp = fopen(path_name.c_str(), "r");
    if (fp == NULL){
      LOG(ERROR) << "Can't open the file " << path_name;
      return false;
    }

    std::string json_data;
    char temp[256];
    while (!feof(fp)){
      int size = fread(temp, sizeof(char), 256, fp);
      json_data.append(temp, size);
    }
    //  Init It
    bool res = InitConfigWithData(json_data);
    fclose(fp);
    return res;
  }

  bool ConfigInstance::InitConfigWithData(const std::string json_data){

    // Parse Json data
    Json::Value root;
    Json::Reader reader;
    bool parse_result = reader.parse(json_data, root);
    if (!parse_result){
      LOG(ERROR) << "Parser json error " << reader.getFormattedErrorMessages();
      return false;
    }
    try{
      ping_timeout_ = root[JSON_PING_TIMEOUT].asUInt();
      LOG(INFO) << JSON_PING_TIMEOUT << " : " << (unsigned int)ping_timeout_;
      // EG: "0.0.0.0"
      bind_addr_ = root[JSON_BIND_ADDR].asString();
      LOG(INFO) << JSON_BIND_ADDR << " : " << bind_addr_;
      // [0,65535]
      bind_port_ = root[JSON_BIND_PORT].asUInt();
      LOG(INFO) << JSON_BIND_PORT << " : " << (unsigned int)bind_port_;


      //Read proxy address and proxy port
      proxy_addr_ = root[JSON_PROXY_ADDR].asString();
      LOG(INFO) << JSON_PROXY_ADDR << " : " << proxy_addr_;
      // [0,65535]
      proxy_port_ = root[JSON_PROXY_PORT].asUInt();
      LOG(INFO) << JSON_PROXY_PORT << " : " << (unsigned int)proxy_port_;

      //
      thread_num_ = root[JSON_THREAD_NUMBER].asUInt();
      LOG(INFO) << JSON_THREAD_NUMBER << " : " << (unsigned int)thread_num_;

      host_url_ = root[JSON_CENTER_SERVER_HOST_URL].asString();
      ping_url_ = root[JSON_CENTER_SERVER_PING_URL].asString();
      LOG(INFO) << JSON_CENTER_SERVER_HOST_URL << " : " << host_url_;
      LOG(INFO) << JSON_CENTER_SERVER_PING_URL << " : " << ping_url_;

    }
    catch (std::exception& e){
      LOG(ERROR) << e.what();
      return true;
    }
    return true;
  }

}